#include "Tracer.h"
#include "TracerServer.h"
#include "CommandPipe.h"
#include "Utils.h"

#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

TracerServer::TracerServer()
{
    m_enable = false;
    m_ptsDev.clear();
}

TracerServer::~TracerServer()
{
}

void TracerServer::onNewConnection(Socket* connSocket)
{
    while (1) 
    {
        char buf[64] = {0};
        int ret=connSocket->readData(buf, sizeof(buf)-1,500);
        if (ret>0)
        {
            /* 控制消息格式 
             * 开启消息  "1:/dev/pts/0"
             * 关闭消息  "0:/dev/pts/0"
             */
            std::string msg(buf);
            if (msg.size()>=12) 
            {
                if (msg.substr(1,10)==":/dev/pts/") 
                {
                    m_enable = !!atoi(msg.substr(0,1).c_str());
                    m_ptsDev = msg.substr(2);
                    if (m_enable) {
                        attachTracer();
                    } else {
                        disattachTracer();
                    }
                }
            }

        }
        else if (ret<0)
        {
            continue;
        }
        else/* 客户端已断开连接 */
        {
            disattachTracer();
            break;
        }
    }
}

bool TracerServer::attachTracer()
{
    TRACE_INFO_CLASS("[%s] attach with tracer.\n",m_ptsDev.c_str());
    if (!m_enable || m_ptsDev.empty())
    {
        return false;
    }          
    close(1);
    close(2);
    /* 在新终端打开标准输出 */
    int ret = (int)open(m_ptsDev.c_str(), 1);
    if(ret<0)
    {
         TRACE_ERR_CLASS("redirect stdout to %s error:%s.\n",m_ptsDev.c_str(), ERROR_STRING);
         return false;    
    }
    /* 在新终端打开标准错误输出 */
    ret = (int)open(m_ptsDev.c_str(), 2);
    if(ret<0)
    {
        TRACE_ERR_CLASS("redirect stderr to %s error:%s.\n", m_ptsDev.c_str(), ERROR_STRING); 
        return false;
    }
    fflush(NULL);
    return true;
}

bool TracerServer::disattachTracer()
{
    TRACE_INFO_CLASS("[%s] disattach with tracer.\n",m_ptsDev.c_str());
    std::string ttyName = CommandPipe::execute("tty");
    if (ttyName.empty()) {
        return false;
    }
    ttyName = Utils::trimEndingBlank(ttyName);
    /* 在当前终端重新打开标准输出和标准错误输出 */
    freopen(ttyName.c_str(),"w",stdout);
    freopen(ttyName.c_str(),"w",stderr);
    return true;
}
